package inter.authorization.manager.impl;

import inter.authorization.manager.AppSecretManager;
import inter.authorization.model.AppSecretModel;
import inter.config.Constants;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.stereotype.Component;

import com.tencent.common.MD5;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 通过Redis存储和验证appSecret的实现类
 * 
 * @see inter.authorization.manager.AppSecretManager
 * @author Max
 * @date 2016/10/24.
 */
@Component
public class RedisAppSecretManager implements AppSecretManager {

	
	private RedisTemplate<String, String> redis;

	@Autowired
	public void setRedis(RedisTemplate<String, String> redis) {
		this.redis = redis;
		// 更改对应的序列化方案
//		redis.setKeySerializer(new JdkSerializationRedisSerializer());
	}

	public AppSecretModel createAppSecret(String appId) {
		// 使用uuid作为源appSecret
		String appSecret = UUID.randomUUID().toString().replace("-", "");
		AppSecretModel model = new AppSecretModel(appId, appSecret);
		redis.boundValueOps(appId).set(appSecret, Constants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
		return model;
	}

	public AppSecretModel getAppSecret(String authentication) {
		if (authentication == null || authentication.length() == 0) {
			return null;
		}
		String[] param = authentication.split("_");
		if (param.length != 2) {
			return null;
		}
		// 使用userId和源appSecret简单拼接成的appSecret，可以增加加密措施
		String appId = param[0];
		String appSecret = param[1];
		return new AppSecretModel(appId, appSecret);
	}

	public boolean checkAppSecret(AppSecretModel model,String nonce,String timestamp,String signature) {
		if (model == null) {
			return false;
		}
		String appSecret = redis.boundValueOps(model.getAppId()).get();//redis数据库存储的AppSecret值
		String signStr = MD5.MD5Encode(appSecret + nonce+timestamp);
		if (signStr == null || !signStr.equals(signature)) {
			return false;
		}
		// 如果验证成功，说明此用户进行了一次有效操作，延长appSecret的过期时间
		redis.boundValueOps(model.getAppId()).expire(Constants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
		return true;
	}

	public void deleteAppSecret(String appId) {
		redis.delete(appId);
	}
}
